package promote.brozen.netty.jav.aio;

import java.nio.ByteBuffer;
import java.nio.channels.CompletionHandler;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Brozen
 * @date 2020/9/27 1:48 PM
 * @email brozen@qq.com
 */
public class AioClientConnector implements CompletionHandler<Void, AioClient> {

    private AtomicReference<Thread> sinThreadRef = new AtomicReference<>(null);

    private AioClient client;

    public AioClientConnector(AioClient client) {
        this.client = client;
    }

    @Override
    public void completed(Void result, AioClient attachment) {
        System.out.println("连接服务端成功！");

        // 连接成功后，启动异步接收消息
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        AioReader reader = new AioReader(client.asc, buffer);
        reader.setRole("Client");
        client.asc.read(buffer, reader, reader);

        // 连接成功后，启动控制台输入监听器
        if (sinThreadRef.get() != null) {
            return;
        } else {
            Thread thread = new Thread(this::readAndSend);
            if (sinThreadRef.compareAndSet(null, thread)) {
                thread.start();
            }
        }
    }

    private void readAndSend() {
        Scanner scanner = new Scanner(System.in);
        String line;
        while (!(line = scanner.nextLine()).equalsIgnoreCase("exit")) {
            byte[] data = line.getBytes();
            ByteBuffer buffer = ByteBuffer.allocate(data.length);
            buffer.put(data);
            buffer.flip();

            final String msg = line;
            client.asc.write(buffer, this, new CompletionHandler<Integer, AioClientConnector>() {
                @Override
                public void completed(Integer result, AioClientConnector attachment) {
                    System.out.println("ClientSend: " + msg);
                }

                @Override
                public void failed(Throwable exc, AioClientConnector attachment) {
                    System.out.println("客户端发送消息失败！");
                    exc.printStackTrace();
                }
            });
        }
    }

    @Override
    public void failed(Throwable exc, AioClient attachment) {
        System.out.println("连接服务端失败！");
        exc.printStackTrace();
    }
}
